package com.blackice.control.tools; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import com.blackice.control.R; import com.blackice.control.util.CMDProcessor; public class VoltageControl extends Activity { private static final String TAG = "VoltageControlActivity"; public static final String KEY_APPLY_BOOT = "apply_voltages_at_boot"; public static final String MV_TABLE0 = "/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table"; public static final String MV_TABLE1 = "/sys/devices/system/cpu/cpu1/cpufreq/UV_mV_table"; private static final int DIALOG_EDIT_VOLT = 0; private List<Voltage> mVoltages; private ListAdapter mAdapter; private static SharedPreferences preferences; private Voltage mVoltage; @Override public void onCreate(Bundle savedInstanceState) { preferences = PreferenceManager.getDefaultSharedPreferences(this); super.onCreate(savedInstanceState); setContentView(R.layout.voltage); final ListView listView = (ListView) findViewById(R.id.ListView); final CheckBox cb = (CheckBox) findViewById(R.id.applyAtBoot); mAdapter = new ListAdapter(getApplicationContext()); mVoltages = getVolts(preferences); if (mVoltages.isEmpty()) { ((TextView) findViewById(R.id.emptyList)) .setVisibility(View.VISIBLE); ((LinearLayout) findViewById(R.id.BottomBar)) .setVisibility(View.GONE); } cb.setChecked(preferences.getBoolean(KEY_APPLY_BOOT, false)); cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { final SharedPreferences.Editor editor = preferences.edit(); editor.putBoolean(KEY_APPLY_BOOT, isChecked); editor.commit(); } }); ((Button) findViewById(R.id.applyBtn)) .setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { final StringBuilder sb = new StringBuilder(); for (final Voltage volt : mVoltages) { sb.append(volt.getSavedMV() + " "); } new CMDProcessor().su.runWaitFor("busybox echo " + sb.toString() + " > " + MV_TABLE0); if (new File(MV_TABLE1).exists()) { new CMDProcessor().su.runWaitFor("busybox echo " + sb.toString() + " > " + MV_TABLE1); } final List<Voltage> volts = getVolts(preferences); mVoltages.clear(); mVoltages.addAll(volts); mAdapter.notifyDataSetChanged(); } }); mAdapter.setListItems(mVoltages); listView.setAdapter(mAdapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mVoltage = mVoltages.get(position); showDialog(DIALOG_EDIT_VOLT); } }); } public static List<Voltage> getVolts(final SharedPreferences preferences) { final List<Voltage> volts = new ArrayList<Voltage>(); try { BufferedReader br = new BufferedReader(new FileReader(MV_TABLE0), 256); String line = ""; while ((line = br.readLine()) != null) { final String[] values = line.split("\\s+"); if (values != null) { if (values.length >= 2) { final String freq = values[0].replace("mhz:", ""); final String currentMv = values[1]; final String savedMv = preferences.getString(freq, currentMv); final Voltage voltage = new Voltage(); voltage.setFreq(freq); voltage.setCurrentMV(currentMv); voltage.setSavedMV(savedMv); volts.add(voltage); } } } br.close(); } catch (FileNotFoundException e) { Log.d(TAG, MV_TABLE0 + " does not exist"); } catch (IOException e) { Log.d(TAG, "Error reading " + MV_TABLE0); } return volts; } private static final int[] STEPS = new int[] { 600, 625, 650, 675, 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, 1525, 1550, 1575, 1600 }; private static int getNearestStepIndex(final int value) { int index = 0; for (int i = 0; i < STEPS.length; i++) { if (value > STEPS[i]) { index++; } else { break; } } return index; } protected Dialog onCreateDialog(final int id) { switch (id) { case DIALOG_EDIT_VOLT: final LayoutInflater factory = LayoutInflater.from(this); final View voltageDialog = factory.inflate(R.layout.voltage_dialog, null); final EditText voltageEdit = (EditText) voltageDialog .findViewById(R.id.voltageEdit); final SeekBar voltageSeek = (SeekBar) voltageDialog.findViewById(R.id.voltageSeek); final TextView voltageMeter = (TextView) voltageDialog .findViewById(R.id.voltageMeter); final String savedMv = mVoltage.getSavedMV(); final int savedVolt = Integer.parseInt(savedMv); voltageEdit.setText(savedMv); voltageEdit.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable arg0) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { final String text = voltageEdit.getText().toString(); int value = 0; try { value = Integer.parseInt(text); } catch (NumberFormatException nfe) { return; } voltageMeter.setText(text + " mV"); final int index = getNearestStepIndex(value); voltageSeek.setProgress(index); } }); voltageMeter.setText(savedMv + " mV"); voltageSeek.setMax(40); voltageSeek.setProgress(getNearestStepIndex(savedVolt)); voltageSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar sb, int progress, boolean fromUser) { if (fromUser) { final String volt = Integer.toString(STEPS[progress]); voltageMeter.setText(volt + " mV"); voltageEdit.setText(volt); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } }); return new AlertDialog.Builder(VoltageControl.this) .setTitle(mVoltage.getFreq() + " MHz Voltage") .setView(voltageDialog) .setPositiveButton("Save", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { removeDialog(id); final String value = voltageEdit.getText().toString(); SharedPreferences.Editor editor = preferences.edit(); editor.putString(mVoltage.getFreq(), value); editor.commit(); mVoltage.setSavedMV(value); mAdapter.notifyDataSetChanged(); } }) .setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface arg0) { removeDialog(id); } }) .create(); default: return null; } }; public class ListAdapter extends BaseAdapter { private LayoutInflater mInflater; private List<Voltage> results; public ListAdapter(Context context) { mInflater = LayoutInflater.from(context); } @Override public int getCount() { return results.size(); } @Override public Object getItem(int position) { return results.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_volt, null); holder = new ViewHolder(); holder.mFreq = (TextView) convertView.findViewById(R.id.Freq); holder.mCurrentMV = (TextView) convertView.findViewById(R.id.mVCurrent); holder.mSavedMV = (TextView) convertView.findViewById(R.id.mVSaved); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } final Voltage voltage = mVoltages.get(position); holder.setFreq(voltage.getFreq()); holder.setCurrentMV(voltage.getCurrentMV()); holder.setSavedMV(voltage.getSavedMV()); return convertView; } public void setListItems(List<Voltage> mVoltages) { results = mVoltages; } public class ViewHolder { private TextView mFreq; private TextView mCurrentMV; private TextView mSavedMV; public void setFreq(final String freq) { mFreq.setText(freq + " MHz"); } public void setCurrentMV(final String currentMv) { mCurrentMV.setText(currentMv + " mV current"); } public void setSavedMV(final String savedMv) { mSavedMV.setText(savedMv + " mV saved"); } } } }